package  com.fyyg.common.page;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 分页结果对象
 * @author hang.ouyang
 *
 * @date 2016年3月17日 上午9:37:33
 */
public class PageData<T> implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4406579446827893741L;
	
	public final static int DEFAULT_PAGE_NO = 1;
	public final static int DEFAULT_PAGE_SIZE = 20;

	private List<T> pageData = new ArrayList<T>(); //分页查询返回的List结果
	private Map<String,Object> mapData = new HashMap<>();
	private int pageNo = DEFAULT_PAGE_NO; //跳转页数，默认第一页
	private int pageSize = DEFAULT_PAGE_SIZE;//每页的记录数,默认10条
	private int dataTotal; //总记录数
	private int pageTotal; //总页数
	private boolean prevPage = false;//是否有上一页
	private boolean nextPage = false;//是否有下一页
	
	private int pageNumStart;// 页码显示开始listbegin;
	private int pageNumEnd;// 页码显示结束listend;
	private int showPageNum = 5;// 显示页码个数，默认是5

	/**
	 * Hessian反序列化需要使用默认构造函数
	 */
	public PageData() {

	}

	public PageData(int pageNo, int pageSize, int dataTotal) {
		this.pageNo = pageNo;
		this.pageSize = pageSize;
		this.dataTotal = dataTotal;
		this.calcPageTotal();// 计算总页数;
		refresh();
		setPageNumEnd(pageNumEnd);
		setPageNumStart(pageNumStart);
	}

	
	public PageData(int pageNo, int pageSize, int dataTotal, List<T> pageData) {
		this.pageNo = pageNo;
		this.pageSize = pageSize;
		this.dataTotal = dataTotal;
		this.pageData = pageData;
		this.calcPageTotal();// 计算总页数;
		refresh();
		setPageNumEnd(pageNumEnd);
		setPageNumStart(pageNumStart);
	}

	/**
	 * 计算总页数
	 * 
	 * @author hang.ouyang
	 * @date 2016年3月17日 上午9:42:07
	 */
	private void calcPageTotal() {
		if (dataTotal == 0) {
			this.pageTotal = 0;
		} else {
			if (dataTotal % pageSize == 0) {
				this.pageTotal = dataTotal / pageSize;
			} else {
				this.pageTotal = dataTotal / pageSize + 1;
			}
		}
	}

	/**
	 * 刷新当前分页对象数据
	 * 
	 * @author hang.ouyang
	 * @date 2016年3月17日 上午9:42:28
	 */
	private void refresh() {
		if (pageTotal <= 1) {
			prevPage = false;
			nextPage = false;
		} else if (pageNo == 1) {
			prevPage = false;
			nextPage = true;
		} else if (pageNo == pageTotal) {
			prevPage = true;
			nextPage = false;
		} else {
			prevPage = true;
			nextPage = true;
		}
	}


	public List<T> getPageData() {
		return pageData;
	}

	public void setPageData(List<T> pageData) {
		this.pageData = pageData;
	}

	
	public int getPageSize() {
		return pageSize;
	}

	
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	
	public int getPageNo() {
		return pageNo;
	}

	
	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	
	public int getDataTotal() {
		return dataTotal;
	}

	
	public void setDataTotal(int dataTotal) {
		this.dataTotal = dataTotal;
		this.calcPageTotal();// 计算总页数
		this.refresh();
	}

	
	public int getPageTotal() {
		return pageTotal;
	}

	
	public void setPageTotal(int pageTotal) {
		this.pageTotal = pageTotal;
	}

	
	public boolean hasPrevPage() {
		return prevPage;
	}

	
	public void setPrevPage(boolean prevPage) {
		this.prevPage = prevPage;
	}

	
	public boolean hasNextPage() {
		return nextPage;
	}

	
	public void setNextPage(boolean nextPage) {
		this.nextPage = nextPage;
	}

	
	public int getStartOfPage() {
		pageNo = pageNo <= 0 ? 1 : pageNo ;
		return (pageNo - 1) * pageSize;
	}

	public boolean isPrevPage() {
		return prevPage;
	}

	public boolean isNextPage() {
		return nextPage;
	}

	private static <T> List<T> subList(List<T> list, int pageNo, int pageSize) {
		// 初始化每页尺寸和页号
		pageSize = (pageSize <= 0 ? 10 : pageSize);
		pageNo = (pageNo <= 0 ? 1 : pageNo);

		// 计算开始结束位置
		int begin = (pageSize * (pageNo - 1) > list.size() ? list.size() : pageSize * (pageNo - 1));
		int end = (pageSize * pageNo > list.size() ? list.size() : pageSize * pageNo);

		// 返回分页数据
		return new ArrayList<T>(list.subList(begin, end));
	}

	/**
	 * 取得List的第N页的DataPage对象
	 * @param list 要分页的list
	 * @param pageNo 第几页，第一页为1
	 * @param pageSize  每页记录数
	 * @return 
	 * @author hang.ouyang
	 * @date 2016年3月17日 上午9:55:13
	 */
	public static <T> PageData<T> pageList(List<T> list, int pageNo,
			int pageSize) {
		List<T> l = subList(list, pageNo, pageSize);
		return new PageData<T>(pageNo, pageSize, list.size(), l);
	}

	public int getPageNumStart() {
		return pageNumStart;
	}

	public void setPageNumStart(int pageNumStart) {
		// 显示页数的一半
		int halfPage = (int) Math.ceil((double) showPageNum / 2);
		if (halfPage >= pageNo) {
			this.pageNumStart = 1;
		} else {
			if (pageNo + halfPage > pageTotal) {
				this.pageNumStart = (pageTotal - showPageNum + 1) <= 0 ? 1
						: (pageTotal - showPageNum + 1);
			} else {
				this.pageNumStart = pageNo - halfPage + 1;
			}
		}
	}

	public int getPageNumEnd() {
		return pageNumEnd;
	}

	public void setPageNumEnd(int pageNumEnd) {
		// 显示页数的一半
		int halfPage = (int) Math.ceil((double) showPageNum / 2);
		if (halfPage >= pageNo) {
			// this.pageNumEnd = showPageNum;
			this.pageNumEnd = showPageNum > pageTotal ? pageTotal : showPageNum;
		} else {
			if (pageNo + halfPage >= pageTotal) {
				this.pageNumEnd = pageTotal;
			} else {
				this.pageNumEnd = pageNo + halfPage;
			}
		}
	}
	public Map<String, Object> getMapData() {
		return mapData;
	}

	public void setMapData(Map<String, Object> mapData) {
		this.mapData = mapData;
	}

	public int getShowPageNum() {
		return showPageNum;
	}

	public void setShowPageNum(int showPageNum) {
		this.showPageNum = showPageNum;
	}

	@Override
	public String toString() {
		return String
				.format("PageParam [p=%s, pageNo=%s, pageSize=%s, dataTotal=%s, pageTotal=%s, prevPage=%s, nextPage=%s, pageNumStart=%s, pageNumEnd=%s]",
						pageData, pageNo, pageSize, dataTotal, pageTotal,
						prevPage, nextPage, pageNumStart, pageNumEnd);
	}

	public static void main(String[] args) {
		List<String> l = new ArrayList<String>();
		l.add("123456");
		l.add("654321");

		PageData<String> p = pageList(l, 1, 1);
		System.out.println(p);
	}
}
